From 90434d92296cf0a872182088f4f661ddffff7d58 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Fri, 13 Aug 2004 12:10:18 +0000 Subject: [PATCH] bitkeeper revision 1.1159.1.50 (411cafaaPlpV28_c19BEAsmasMfTcg) Hacking to try to get migrate to localhost going. --- tools/libxc/xc_linux_restore.c | 2 +- tools/python/xen/xend/XendDomain.py | 54 +++++++++++++++++------ tools/python/xen/xend/XendDomainInfo.py | 5 +++ tools/python/xen/xend/server/SrvDomain.py | 8 +++- tools/xfrd/xen_domain.c | 37 ++++++++++++++++ tools/xfrd/xen_domain.h | 1 + tools/xfrd/xfrd.c | 16 ++++++- 7 files changed, 104 insertions(+), 19 deletions(-) diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 62050c83eb..71b473d10c 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -224,7 +224,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt) /* XXX create domain on CPU=-1 so that in future it auto load ballances by default */ if ( xc_domain_create( xc_handle, nr_pfns * (PAGE_SIZE / 1024), - name, -1, &dom ) ) + "", -1, &dom ) ) { xcio_error(ioctxt, "Could not create domain. pfns=%d, %dKB", nr_pfns,nr_pfns * (PAGE_SIZE / 1024)); diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index bffbdee46b..7dead8f820 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -197,7 +197,11 @@ class XendDomain: """ self.domain_by_id[info.id] = info self.domain_db[info.id] = info.sxpr() - self.domain_by_name[info.name] = info + for k, d in self.domain_by_name.items(): + if k != d.name: + del self.domain_by_name[k] + if info.name: + self.domain_by_name[info.name] = info self.sync_domain(info.id) if notify: eserver.inject('xend.domain.created', [info.name, info.id]) @@ -207,12 +211,13 @@ class XendDomain: @param id: domain id @param notify: send a domain died event if true """ + for info in self.domain_by_name.values(): + if info.id == id: + del self.domain_by_name[info.name] if id in self.domain_by_id: info = self.domain_by_id[id] - if notify: eserver.inject('xend.domain.died', [info.name, info.id]) - if info.name in self.domain_by_name: - del self.domain_by_name[info.name] del self.domain_by_id[id] + if notify: eserver.inject('xend.domain.died', [info.name, info.id]) if id in self.domain_db: del self.domain_db[id] self.db.delete(id) @@ -223,6 +228,10 @@ class XendDomain: """ self.reap_cancel() domlist = xc.domain_getinfo() + #for d in domlist: + # print 'reap> xen: ', d['dom'], d + #for d in self.domain_by_id.values(): + # print 'reap> xend: ', d.id, d.info casualties = [] for d in domlist: dead = 0 @@ -240,9 +249,12 @@ class XendDomain: log.debug('XendDomain>reap> shutdown id=%s reason=%s', id, reason) if reason in ['suspend']: dominfo = self.domain_by_id.get(id) - name = (dominfo and dominfo.name) or '??' - eserver.inject('xend.domain.suspended', [name, id]) - continue + if dominfo.is_terminated(): + log.debug('XendDomain>reap> Suspended domain died id=%s', id) + else: + name = (dominfo and dominfo.name) or '??' + eserver.inject('xend.domain.suspended', [name, id]) + continue if reason in ['poweroff', 'reboot']: self.domain_restart_schedule(id, reason) destroyed += 1 @@ -257,6 +269,10 @@ class XendDomain: """ self.refresh_cancel() domlist = xc.domain_getinfo() + #for d in domlist: + # print 'refresh> xen: ', d['dom'], d + #for d in self.domain_by_id.values(): + # print 'refresh> xend: ', d.id, d.info # Index the domlist by id. # Add entries for any domains we don't know about. doms = {} @@ -344,6 +360,15 @@ class XendDomain: deferred.addCallback(cbok) return deferred + def domain_setname(self, dom, name): + """Set the name of a domain. + For internal use only. + + @param dom: domain id + @param name: domain name + """ + return xc.domain_setname(dom=dom, name=name) + def domain_restart(self, dominfo): """Restart a domain. @@ -358,22 +383,23 @@ class XendDomain: deferred.addCallback(cbok) return deferred - def domain_configure(self, id, config): + def domain_configure(self, id, vmconfig): """Configure an existing domain. This is intended for internal use by domain restore and migrate. - @param id: domain id - @param config: configuration + @param id: domain id + @param vmconfig: vm configuration @return: deferred """ - print 'domain_configure>', id, config + print 'domain_configure>', id, vmconfig + config = sxp.child_value(vmconfig, 'config') dominfo = self.domain_lookup(id) print 'domain_configure>', 'dominfo=', dominfo for dinfo in self.domain_by_id.values(): - print 'domain', dinfo.id, dinfo.name - log.debug('domain_configure> id=%s config=%s', id, str(config)) + print 'domain', 'id=', dinfo.id, 'name=', dinfo.name + log.debug('domain_configure> id=%s config=%s', str(id), str(config)) if dominfo.config: - raise XendError("Domain already configured: " + dominfo.name) + raise XendError("Domain already configured: " + dominfo.id) def cbok(dominfo): self._add_domain(dominfo) return dominfo diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 472cc0f74c..ce01d28b0a 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -475,6 +475,8 @@ class XendDomainInfo: if not dominfo: return print 'check_name>', 'dom=', dominfo.name, dominfo.dom, 'self=', name, self.dom + if dominfo.is_terminated(): + return if not self.dom or (dominfo.dom != self.dom): raise VmError('vm name clash: ' + name) @@ -490,6 +492,8 @@ class XendDomainInfo: try: self.name = sxp.child_value(config, 'name') self.check_name(self.name) + if self.restore and self.dom: + xc.domain_setname(self.dom, self.name) self.memory = int(sxp.child_value(config, 'memory')) if self.memory is None: raise VmError('missing memory size') @@ -629,6 +633,7 @@ class XendDomainInfo: if self.restart_pending(): self.console.deregisterChannel() else: + log.debug('Closing console, domain %s', self.id) self.console.close() chan = xend.getDomChannel(self.dom) if chan: diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index 8975148819..aed8fd7e57 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -21,10 +21,14 @@ class SrvDomain(SrvDir): self.xconsole = XendConsole.instance() def op_configure(self, op, req): + """Configure an existing domain. + Configure is unusual in that it requires a domain id, + not a domain name. + """ fn = FormFn(self.xd.domain_configure, - [['dom', 'str'], + [['dom', 'int'], ['config', 'sxpr']]) - deferred = fn(req.args, {'dom': self.dom.name}) + deferred = fn(req.args, {'dom': self.dom.dom}) deferred.addErrback(self._op_configure_err, req) return deferred diff --git a/tools/xfrd/xen_domain.c b/tools/xfrd/xen_domain.c index a5d18c0199..2f6d0fa8f2 100644 --- a/tools/xfrd/xen_domain.c +++ b/tools/xfrd/xen_domain.c @@ -304,7 +304,44 @@ int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n){ CURLFORM_COPYNAME, "op", CURLFORM_COPYCONTENTS, "configure", CURLFORM_END); + if(formcode){ + eprintf("> Error adding op field.\n"); + err = -EINVAL; + goto exit; + } + // POST the form. + curl_easy_setopt(curl, CURLOPT_HTTPPOST, form); + err = curlresult(curl); + exit: + if(curl) curl_easy_cleanup(curl); + if(form) curl_formfree(form); + dprintf("< err=%d\n", err); + return err; +} + +/** Get xend to unpause a domain. + * + * @param dom domain id + * @return 0 on success, error code otherwise + */ +int xen_domain_unpause(uint32_t dom){ + int err = 0; + CURL *curl = NULL; + char url[128] = {}; + int url_n = sizeof(url); + struct curl_httppost *form = NULL, *last = NULL; + CURLFORMcode formcode = 0; + dprintf("> dom=%u\n", dom); + + err = curlsetup(&curl, url, url_n, "http://localhost:%d/xend/domain/%u", XEND_PORT, dom); + if(err) goto exit; + + // Op field. + formcode = curl_formadd(&form, &last, + CURLFORM_COPYNAME, "op", + CURLFORM_COPYCONTENTS, "unpause", + CURLFORM_END); if(formcode){ eprintf("> Error adding op field.\n"); err = -EINVAL; diff --git a/tools/xfrd/xen_domain.h b/tools/xfrd/xen_domain.h index 4618c642b7..4b2e1c7e04 100644 --- a/tools/xfrd/xen_domain.h +++ b/tools/xfrd/xen_domain.h @@ -12,4 +12,5 @@ extern int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmc extern int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n); +extern int xen_domain_unpause(uint32_t dom); #endif diff --git a/tools/xfrd/xfrd.c b/tools/xfrd/xfrd.c index 3d0cfa3e66..c5abcdcf1b 100644 --- a/tools/xfrd/xfrd.c +++ b/tools/xfrd/xfrd.c @@ -605,13 +605,18 @@ int xfr_send_state(XfrState *state, Conn *xend, Conn *peer){ // Send xfr message and the domain state. err = xfr_send_xfr(peer, state->vmid); if(err) goto exit; + dprintf(">*** Sending domain %u\n", state->vmid); err = xen_domain_snd(xend, peer->out, state->vmid, state->vmconfig, state->vmconfig_n); + dprintf(">*** Sent domain %u\n", state->vmid); if(err) goto exit; // Sending the domain suspends it, and there's no way back. // So destroy it now. If anything goes wrong now it's too late. + dprintf(">*** Destroying domain %u\n", state->vmid); err = xfr_vm_destroy(xend, state->vmid); if(err) goto exit; + err = xfr_error(peer, err); + if(err) goto exit; IOStream_flush(peer->out); // Read the response from the peer. err = Conn_sxpr(peer, &sxpr); @@ -778,14 +783,21 @@ int xfr_save(Args *args, XfrState *state, Conn *xend, char *file){ int xfr_recv(Args *args, XfrState *state, Conn *peer){ int err = 0; time_t t0 = time(NULL), t1; + Sxpr sxpr; dprintf(">\n"); err = xen_domain_rcv(peer->in, &state->vmid_new, &state->vmconfig, &state->vmconfig_n); if(err) goto exit; - + // Read from the peer. This is just so we wait before configuring. + // When migrating to the same host the peer must destroy the domain + // before we configure the new one. + err = Conn_sxpr(peer, &sxpr); + if(err) goto exit; + sleep(2); err = xen_domain_configure(state->vmid_new, state->vmconfig, state->vmconfig_n); if(err) goto exit; - + err = xen_domain_unpause(state->vmid_new); + if(err) goto exit; // Report new domain id to peer. err = xfr_send_xfr_ok(peer, state->vmid_new); if(err) goto exit; -- 2.30.2